package com.rocpenghua.fastdfs.client.config;

import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import java.io.*;
import java.util.Objects;

/**
 * @author RocPengHua
 * @date 2022/6/18 14:11
 */
public class FastdfsClient {
    private static final String CONF_FILENAME = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath() + "fdfs_client.conf";

    private static StorageClient storageClient = null;

    public static final String DEFAULT_GROUP = "group1";

    public static final String DOT = ".";

    static {
        try {
            ClientGlobal.init(CONF_FILENAME);
            TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
            TrackerServer trackerServer = trackerClient.getConnection();
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient = new StorageClient(trackerServer, storageServer);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     *
     * @param inputStream 上传的文件流
     * @param fileName    上传的文件名
     * @return [groupName，remoteFileName]
     */
    public static String[] uploadFile(InputStream inputStream, String fileName) {

        try {
            // 文件的元数据
            NameValuePair[] metaArr = new NameValuePair[2];
            // 第一组元数据，文件的原始名称
            metaArr[0] = new NameValuePair("file name", fileName);
            //第二组元数据
            metaArr[1] = new NameValuePair("file length", inputStream.available() + "");

            byte[] fileBuff = null;
            int len = inputStream.available();
            fileBuff = new byte[len];
            inputStream.read(fileBuff);
            // 上传文件。参数含义：要上传的文件的内容（使用字节数组传递），上传的文件的类型（扩展名），元数据
            return storageClient.upload_file(fileBuff, getFileExt(fileName), metaArr);
        } catch (IOException | MyException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 上传文件
     *
     * @param file     文件
     * @param fileName 文件名
     * @return
     */
    public static String[] uploadFile(File file, String fileName) {
        try {
            return uploadFile(new FileInputStream(file), fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除文件
     *
     * @param groupName      组名，默认 group1
     * @param remoteFileName 远程文件名 ： M00/00/00/wKhle2KsilWACukrAAAAW5T75rI594.txt
     * @return 0：成功，非0失败
     */
    public static int deleteFile(String groupName, String remoteFileName) {
        try {
            return storageClient.delete_file(groupName, remoteFileName);
        } catch (IOException | MyException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 删除文件
     *
     * @param remoteFileName 远程文件名 ： M00/00/00/wKhle2KsilWACukrAAAAW5T75rI594.txt
     * @return 0：成功，非0失败
     */
    public static int deleteFile(String remoteFileName) {
        try {
            return storageClient.delete_file(DEFAULT_GROUP, remoteFileName);
        } catch (IOException | MyException e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 修改文件
     * @param oldGroupName 原文件组
     * @param oldFileName 原文件名
     * @param inputStream 新文件流
     * @param fileName 新文件名
     * @return 返回空则为失败
     */
    public static String[] modifyFile(String oldGroupName, String oldFileName, InputStream inputStream, String fileName) {
        String[] fileIds = null;
        try {
            fileIds = uploadFile(inputStream, fileName);
            if (fileIds == null) {
                return null;
            }
            int delResult = deleteFile(oldGroupName, oldFileName);
            if (delResult != 0) {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return fileIds;
    }
    /**
     * 修改文件
     * @param oldGroupName 原文件组
     * @param oldFileName 原文件名
     * @param file 新文件
     * @param fileName 新文件名
     * @return 返回空则为失败
     */
    public static String[] modifyFile(String oldGroupName, String oldFileName, File file, String fileName) {
        String[] fileIds;
        try {
            // 先上传
            fileIds = uploadFile(file, fileName);
            if (fileIds == null) {
                return null;
            }
            // 再删除
            int delResult = deleteFile(oldGroupName, oldFileName);
            if (delResult != 0) {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return fileIds;
    }

    /**
     * 文件下载
     * @param groupName 组名
     * @param remoteFileName 文件名
     * @return 返回文件流
     */
    public static InputStream downloadFile(String groupName, String remoteFileName){
        try {
            byte[] bytes = storageClient.download_file(groupName,remoteFileName);
            return new ByteArrayInputStream(bytes);
        } catch (IOException | MyException e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 文件下载
     * @param remoteFileName 文件名
     * @return 返回文件流
     */
    public static InputStream downloadFile(String remoteFileName){
        return downloadFile(DEFAULT_GROUP,remoteFileName);
    }
    public static NameValuePair[] getMetaData(String groupName, String remoteFileName) {
        try {
            NameValuePair[] nvp = storageClient.get_metadata(groupName, remoteFileName);
            return nvp;
        } catch (IOException | MyException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String getFileExt(String fileName) {
        if (StringUtils.isEmpty(fileName) || !fileName.contains(DOT)) {
            return "";
        } else {
            return fileName.substring(fileName.lastIndexOf(DOT) + 1);
        }
    }


    public static void main(String[] args) {
//        File file = new File("E:\\hexo\\blog\\themes\\hexo-theme-flexblock\\source\\images\\upload\\2021\\10\\4.jpg");
//        String fileName = UUID.randomUUID().toString()+".jpg";
//        String[] results = FastdfsClient.uploadFile(file,fileName);
//        System.out.println(Arrays.toString(results)); // [group1, M00/00/00/wKhle2KteBiAe5isAAPsZnLLhZ8165.jpg]

//        File file = new File("E:\\hexo\\blog\\themes\\hexo-theme-flexblock\\source\\images\\upload\\2021\\10\\5.jpg");
//        String fileName = UUID.randomUUID().toString()+".jpg";
//        String[] results = FastdfsClient.modifyFile("group1", "M00/00/00/wKhle2KteBiAe5isAAPsZnLLhZ8165.jpg", file, fileName);
//        System.out.println(Arrays.toString(results)); //[group1, M00/00/00/wKhle2KteO6AaMzSAAlxVVFLRR8475.jpg]
//        int i = FastdfsClient.deleteFile("M00/00/00/wKhle2KteBiAe5isAAPsZnLLhZ8165.jpg");
//        System.out.println(i); //2
        InputStream is = null;
        OutputStream os = null;
        try {
             is = FastdfsClient.downloadFile("group1", "M00/00/00/wKhle2KteO6AaMzSAAlxVVFLRR8475.jpg");
             os = new FileOutputStream("E:\\4.jpg");
            int index = 0;
            while ((index = is.read()) != -1){
                os.write(index);
            }
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
